package com.fy.fyspace.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.fy.fyspace.common.annotation.GlobalInterceptor;
import com.fy.fyspace.common.result.Result;
import com.fy.fyspace.constant.KeysConstant;
import com.fy.fyspace.constant.ResultMessageConstant;
import com.fy.fyspace.ex.handler.ExceptionHandler;
import com.fy.fyspace.model.dto.file.DownLoadCodeDTO;
import com.fy.fyspace.model.dto.file.ShareSessionDTO;
import com.fy.fyspace.model.dto.file.ShowShareFileQueryDTO;
import com.fy.fyspace.model.entity.FileInfo;
import com.fy.fyspace.model.vo.file.FolderVO;
import com.fy.fyspace.model.vo.user.UserSessionVO;
import com.fy.fyspace.service.ShowShareService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.net.URLEncoder;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/showShare")
@Api(tags = "分享展示接口")
public class ShowShareController extends BaseController {

    @Autowired
    private ShowShareService showShareService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 获取分享登录信息
     *
     * @param shareId
     * @return
     */
    @PostMapping("/getShareLoginInfo/{shareId}")
    @ApiOperation(value = "获取分享登录信息", notes = "获取分享的登录验证信息")
    public Result getShareLoginInfo(
            @ApiParam(value = "分享ID", required = true) @PathVariable String shareId) {
        return Result.success(showShareService.getShareLoginInfo(shareId));
    }

    /**
     * 获取分享信息
     *
     * @param shareId
     * @return
     */
    @PostMapping("/getShareInfo")
    @ApiOperation(value = "获取分享信息", notes = "获取分享的登录验证信息")
    public Result getShareInfo(HttpSession httpSession, String shareId) {
        log.info("shareId:{}", shareId);
        return  showShareService.getShareInfo(shareId, httpSession);
    }

    /**
     * 检验分享码
     *
     * @param shareId
     * @param code
     * @return
     */
    @PostMapping("/checkShareCode")
    @ApiOperation(value = "验证分享码", notes = "验证分享的访问密码")
    public Result checkShareCode(
            @ApiParam(hidden = true) HttpSession httpSession,
            @ApiParam(value = "分享ID", required = true) String shareId,
            @ApiParam(value = "分享码", required = true) String code) {

        log.info("shareId:{}", shareId);
        log.info("code:{}", code);
        ShareSessionDTO shareSessionDto = showShareService.checkShareCode(httpSession, shareId, code);

        httpSession.setAttribute(KeysConstant.SHARE_CODE_SESSION + shareId, shareSessionDto);
        return Result.success();
    }

    /**
     * 获取分享列表
     *
     * @return
     */
    @PostMapping("/loadFileList")
    @ApiOperation(value = "获取分享列表", notes = "获取分享的文件列表")
    public Result loadFileList(HttpSession httpSession, @RequestBody ShowShareFileQueryDTO shareQueryDTO) {
        log.info("queryDTO:{}", shareQueryDTO);
        return showShareService.loadFileList(httpSession, shareQueryDTO);
    }

    /**
     * 获取发现文件夹目录信息
     *
     * @param shareId
     * @param path
     * @return
     */
    @PostMapping("/getFolderInfo")
    @ApiOperation(value = "获取发现文件夹目录信息", notes = "获取分享的文件夹目录信息")
    public Result getFolderInfo(String shareId, String path) {

        List<FolderVO> foloderVOList = showShareService.getFolderInfo(path);
        return Result.success(foloderVOList);
    }

    /**
     * 查看文件
     *
     * @param shareId
     * @param fileId
     * @return
     */
    @GetMapping("/getFile/{shareId}/{fileId}")
    @ApiOperation(value = "查看文件", notes = "查看分享的文件")
    public void getFile(HttpServletResponse response, @PathVariable String shareId, @PathVariable String fileId) {

        FileInfo fileInfo = showShareService.getFilePath(fileId);
        readFile(response, fileInfo.getFilePath());
    }

    /**创建分享文件下载链接
     *
     * @param shareId
     * @param shareFileIds
     * @param httpSession
     * @return
     */

    @PostMapping("/createDownloadUrl")
    @ApiOperation(value = "创建分享文件下载链接", notes = "创建分享的文件下载链接")
    public Result createDownloadUrl(String shareId, String shareFileIds, HttpSession httpSession) {
        log.info("shareId,fileIds:{},{}", shareId,shareFileIds);
        return Result.success(showShareService.createDownloadURL(httpSession, shareId, shareFileIds));
    }

    /**
     * 加载文件夹
     * 
     * @param filePid
     * @return
     */
    @PostMapping("/loadMyFolder/{filePid}")
    @ApiOperation(value = "加载文件夹", notes = "加载分享的文件夹")
    public Result loadMyFolder(@PathVariable String filePid, HttpSession httpSession) {
        return Result.success(showShareService.loadMyFolder(httpSession, filePid));
    }

    /**
     * 下载文件
     *
     * @param request
     * @param response
     * @param shareId
     * @param fileId
     * @throws Exception
     */
    @GetMapping("/download/{shareId}/{fileId}")
    @ApiOperation(value = "下载文件", notes = "下载分享的文件")
    public void download(HttpServletRequest request, HttpServletResponse response,
            @PathVariable("shareId") String shareId,
            @PathVariable("fileId") String fileId) throws Exception {

        String downLoadCode = (String) request.getSession().getAttribute(KeysConstant.SHARE_CODE_SESSION + shareId);
        String redisDownLoadKey = KeysConstant.DOWNLOAD_KEY + shareId + downLoadCode + fileId;
        Object redisValue = redisTemplate.opsForValue().get(redisDownLoadKey);
        ExceptionHandler.throwIf(StrUtil.isBlank(downLoadCode) || redisValue == null,
                ResultMessageConstant.DOWNLOAD_LINK_EXPIRED);

        DownLoadCodeDTO dto = JSONUtil.toBean(redisValue.toString(), DownLoadCodeDTO.class);

        log.info("redis中的下载数据:{}", dto);

        String filePath = dto.getFilePath();
        String fileName = dto.getFileName();

        // 设置响应头
        response.setContentType("application/x-msdownload; charset=UTF-8");
        if (request.getHeader("User-Agent").toLowerCase().contains("msie")) {
            fileName = URLEncoder.encode(fileName, "UTF-8");
        } else {
            fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
        }
        response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");

        // 更新下载计数
        String countKey = redisDownLoadKey + "count";
        String allCountKey = redisDownLoadKey + "allCount";

        Long currentCount = redisTemplate.opsForValue().increment(countKey);
        Object allCountObj = redisTemplate.opsForValue().get(allCountKey);

        if (allCountObj != null) {
            int allCount = Integer.parseInt(allCountObj.toString());
            log.info("allCount:{}", allCount);
            log.info("count:{}", currentCount);
            // 如果下载完成，清理资源
            if (currentCount != null && currentCount >= allCount) {
                log.info("开始执行清理session和redis");
                request.getSession().removeAttribute(KeysConstant.DOWNLOAD_KEY);
                Boolean delete1 = redisTemplate.delete(allCountKey);
                Boolean delete2 = redisTemplate.delete(countKey);
                log.info("清理结果:{},{}", delete1, delete2);
            }
        }
        readFile(response, filePath);
    }

    /**
     * 保存分享文件
     *
     * @param httpSession
     * @param shareId
     * @param shareFileIds
     * @param myFolderId
     * @return
     */
    @PostMapping("/saveShare")
    @GlobalInterceptor
    @ApiOperation(value = "保存分享文件", notes = "保存分享的文件")
    public Result saveShare(HttpSession httpSession, String shareId, String shareFileIds, String myFolderId) {
        UserSessionVO userSessionVO = (UserSessionVO) httpSession.getAttribute(KeysConstant.LOGIN_SESSION_KEY);
        showShareService.saveShare(userSessionVO, shareId, shareFileIds, myFolderId);
        return Result.success();
    }
}
